package com.googlecode.imanager.client.form;

import com.googlecode.imanager.client.bridge.form.IInputText;
import com.googlecode.imanager.client.event.KeyEvent;
import com.googlecode.imanager.client.event.KeyEventType;
import com.googlecode.imanager.client.util.HasText;
import com.googlecode.imanager.client.util.HasTextSelection;
import com.googlecode.imanager.client.util.Utils;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public abstract class InputText extends InputControl implements IInputText, HasText, HasTextSelection {

    private static final long serialVersionUID = 1L;

    private String text = "";
    private Integer maxLength;  
    private boolean autoTrim;
    
    public InputText() {
        super();
    }

    protected InputText(int width, int height) {
        super(width, height);
    }

    protected String onChanging(String text){
        return text;
    }

    @Override
    protected void handleDefault(KeyEvent e) {
        super.handleDefault(e);
        if (maxLength != null
                && e.getEventType() == KeyEventType.KEY_PRESSED
                && !e.isPreventDefault()
                && maxLength == text.length()){
            e.setPreventDefault(true);
        }
    }

    @Override
    protected void onBlur() {
        super.onBlur();
        if (autoTrim){
            setText(text.trim());
        }
    }

    @Override
    public boolean hasInput() {
        return text.length() > 0;
    }

    @Override
    public void clearInput() {
        setText(null);
    }

    public String getText() {
        return text;
    }
    
    public void setText(String text) {
        if (text == null){
            text = "";
        }
        if (!this.text.equals(text)){
            changeText(text);
        }
    }
    
    @Override
    public void refresh() {
        changeText(text);
        super.refresh();
    }

    final void changeText(String text){
        text = onChanging(text);
        text = checkTextLength(text);
        this.text = text;
        getBridge().setText(text);
        onChanged();
    }

    private String checkTextLength(String text) {
        if (text == null){
            return "";
        }
        if (maxLength != null
                && maxLength < text.length()){
            return text.substring(0, maxLength);
        }
        return text;
    }

    public Integer getMaxLength() {
        return maxLength;
    }

    public void setMaxLength(Integer maxLength) {
        if (maxLength != null
                && maxLength <= 0){
            maxLength = null;
        }
        if (!Utils.isEquals(this.maxLength, maxLength)){
            this.maxLength = maxLength;
            getBridge().setMaxLength(maxLength);
            changeText(text);
        }
    }

    public int getSelectionStart() {
        return getBridge().getSelectionStart();
    }

    public void setSelectionStart(int selectionStart) {
        setSelection(selectionStart, getSelectionEnd());
    }

    public int getSelectionEnd() {
        return getBridge().getSelectionEnd();
    }

    public void setSelectionEnd(int selectionLength) {
        setSelection(getSelectionStart(), selectionLength);
    }

    @Override
    public void setSelection(int selectionStart, int selectionEnd) {
        getBridge().setSelection(selectionStart, selectionEnd);
    }
    
    public void selectAll(){
        setSelection(0, text.length());
    }

    @Override
    public int getCaretPosition() {
        return getBridge().getCaretPosition();
    }

    @Override
    public void setCaretPosition(int caretPosition) {
        getBridge().setCaretPosition(caretPosition);
    }

    public boolean isAutoTrim() {
        return autoTrim;
    }

    public void setAutoTrim(boolean autoTrim) {
        this.autoTrim = autoTrim;
    }

    @Override
    public InputText clone() {
        return (InputText) super.clone();
    }

    @Override
    protected IInputText getBridge() {
        return (IInputText) lookupBridge();
    }
    
}
